# -*- coding: utf-8 -*-
# created on 2017/4/12
#

from mathsolver.functions.base import *
from mathsolver.functions.base.base import new_latex
from sympy.abc import m, n


def exs_expr_default_symbols(expr):
    symbols = []
    if n in expr.free_symbols:
        symbols.append(n)
    if m in expr.free_symbols:
        symbols.append(m)
    return symbols


# "Eequations" 在known里面，迭代求解
# 单个方程
class EXSSolveEq004(BaseFunction):
    def solver(self, *args):
        assert "Eequations" in self.known
        eeqs = self.search("Eequations")
        for eq in eeqs:
            if len(eq) == 2:
                expr = eq[0] - eq[1]
                symbols = exs_expr_default_symbols(expr)
                assert len(symbols) == 1
                symbol = symbols[0]
                answer = None
                for i in range(1, 10000):
                    left = eq[0]
                    right = eq[1]
                    new_left = left.subs({symbol: i})
                    new_right = right.subs({symbol: i})
                    if right != 0:
                        if new_left == new_right != 0:
                            answer = i
                            break
                    else:
                        if new_left == new_right:
                            answer = i
                            break
                self.steps.append(["", "解得: %s = %s" % (new_latex(symbol), new_latex(answer))])
                target = args[0].sympify()
                target_value = target.subs({symbol: answer})
                self.output.append(BaseSymbolValue({target: target_value}))
                self.label.add("解组合方程")
        return self


class EXSSolveEq(BaseFunction):
    CLS = [EXSSolveEq004]

    def solver(self, *args):
        known = self.known
        r = None
        for cl in EXSSolveEq.CLS:
            try:
                new_known = dict(known)
                r = cl(known=new_known, verbose=True).solver(*args)
                break
            except Exception:
                pass
        if not r:
            raise 'try fail'
        return r
